module fiona_dim_mod

  use netcdf

  implicit none

  type dim_type
    integer id
    character(NF90_MAX_NAME) name
    character(256) long_name
    character(60) units
    integer size
    real(8) span(2)
    real(8) length
    logical :: cyclic = .false.
    logical :: flip = .false.
    ! Parallel IO
    logical :: decomp = .false.
  contains
    procedure :: init => dim_init
    procedure :: clear => dim_clear
    final dim_final
  end type dim_type

contains

  subroutine dim_init(this, name, id, size, long_name, units, cyclic, flip, decomp)

    class(dim_type), intent(inout) :: this
    character(*), intent(in) :: name
    integer, intent(in), optional :: id
    integer, intent(in), optional :: size
    character(*), intent(in), optional :: long_name
    character(*), intent(in), optional :: units
    logical, intent(in), optional :: cyclic
    logical, intent(in), optional :: flip
    logical, intent(in), optional :: decomp

    this%name = name
    if (present(long_name)) then
      this%long_name = long_name
    else
      select case (name)
      case ('lon', 'ilon')
        this%long_name = 'Longitude'
      case ('lat', 'ilat')
        this%long_name = 'Latitude'
      case ('lev', 'ilev')
        this%long_name = 'Vertical level'
      case ('time', 'Time')
        this%long_name = 'Time'
      end select
    end if
    if (present(units)) then
      this%units = units
    else
      select case (name)
      case ('lon', 'ilon')
        this%units = 'degrees_east'
      case ('lat', 'ilat')
        this%units = 'degrees_north'
      case ('lev', 'ilev')
        this%units = '1'
      end select
    end if
    if (present(id)) then
      this%id = id
    end if
    if (present(size)) then
      this%size = size
    else
      this%size = NF90_UNLIMITED
    end if
    if (present(cyclic)) then
      this%cyclic = cyclic
    end if
    if (present(flip)) then
      this%flip = flip
    end if
    if (present(decomp)) then
      this%decomp = decomp
    end if

  end subroutine dim_init

  subroutine dim_clear(this)

    class(dim_type), intent(inout) :: this

    this%name = 'N/A'
    this%long_name = 'N/A'
    this%units = 'N/A'
    this%id = 0
    this%size = 0
    this%cyclic = .false.
    this%flip = .false.
    this%decomp = .false.

  end subroutine dim_clear

  subroutine dim_final(this)

    type(dim_type), intent(inout) :: this

    call this%clear()

  end subroutine dim_final

end module fiona_dim_mod
